home *** CD-ROM | disk | FTP | other *** search
/ Aminet 5 / Aminet 5 - March 1995.iso / Aminet / text / misc / pcal_4_5.lha / pcal / pcalinit.c < prev    next >
C/C++ Source or Header  |  1994-10-16  |  7KB  |  273 lines

  1. /*
  2.  * Create a .h file from a .ps file.  Strips out leading and trailing 
  3.  * whitespace, blank lines, and lines consisting solely of comments,
  4.  * except for the very first block of comments/blanklines, which are
  5.  * turned into C comments at the top of the file.
  6.  * 
  7.  *   14-sep-90  Jamie Zawinski  created.
  8.  *
  9.  * Revision history:
  10.  *
  11.  *    4.5    AWR    04/05/94    avoid adding block name comment if
  12.  *                    first line already contains comment
  13.  *
  14.  *            12/08/93    support #BEGIN <name>..#END blocks
  15.  *                    for optional sections of PostScript
  16.  *                    boilerplate (cf. writefil.c,
  17.  *                    pcalinit.ps)
  18.  *
  19.  *            09/09/93    propagate "%%" comments to output file
  20.  *
  21.  *    4.3    AWR    10/15/91    minor tweak to avoid redefinition
  22.  *                    of PROTOS
  23.  *
  24.  *    4.0    AWR    02/25/91    added optional third argument for
  25.  *                    name of array
  26.  *
  27.  *            02/19/91    added function prototypes; documented
  28.  *
  29.  *            01/16/91    Escape " and \ in quoted strings;
  30.  *                    strip trailing comments; skip FF
  31.  *
  32.  *    2.6    JAB    10/18/90    Add exit(0).
  33.  *
  34.  *    2.3    JWZ    09/14/90    Author
  35.  */
  36.  
  37. #include <stdio.h>
  38. #include <ctype.h>
  39. #include <string.h>
  40.  
  41. #ifndef SEEK_SET        /* symbolic definition for fseek() */
  42. #define SEEK_SET    0
  43. #endif
  44.  
  45. #if !defined(PROTOS) && (defined(__STDC__) || defined(AMIGA))
  46. #define PROTOS
  47. #endif
  48.  
  49. #define FALSE    0
  50. #define TRUE    1
  51.  
  52. #define BEGIN_STR    "#BEGIN"    /* block delimiters */
  53. #define END_STR        "#END"
  54.  
  55. #define ARRAY_NAME    "header"    /* default name of array in .h file */
  56.  
  57. #define IS_WHITESPACE(c) \
  58.     ((c) == ' ' || (c) == '\t' || (c) == '\n' || c == '\f')
  59.  
  60. #define IS_POSTSCRIPT(s)    ((s)[0] != '%' && (s)[0] != '\0')
  61.  
  62. #define IS_PSCOMMENT(s)        ((s)[0] == '%' && (s)[1] == '%')
  63.  
  64. #define IS_BEGIN(s)        (strstr((s), BEGIN_STR) == (s))
  65.  
  66. #define IS_END(s)        (strstr((s), END_STR) == (s))
  67.  
  68. /*
  69.  * strip_white: strip leading and trailing whitespace from 'string'; return
  70.  * pointer to first non-whitespace character
  71.  */
  72. char *
  73. #ifdef PROTOS
  74. strip_white(char *string)
  75. #else
  76. strip_white(string)
  77.     char *string;
  78. #endif
  79. {
  80.     int n;
  81.     for (; IS_WHITESPACE(*string); string++)
  82.     ;
  83.     n = strlen(string)-1;
  84.     for (; IS_WHITESPACE(string[n]); n--)
  85.     string[n] = '\0';
  86.     return string;
  87. }
  88.  
  89.  
  90. /*
  91.  * strip_comment: strip comment (unless denoted by "%%") and any preceding
  92.  * whitespace from 'string'; return pointer to 'string'
  93.  */
  94. char *
  95. #ifdef PROTOS
  96. strip_comment(char *string)
  97. #else
  98. strip_comment(string)
  99.     char *string;
  100. #endif
  101. {
  102.     char *p;
  103.     if ((p = strchr(string, '%')) != NULL) {
  104.     if (p[1] == '%')        /* propagate '%%' comments */
  105.         do
  106.         p[0] = p[1];        /* squeeze out initial '%' */
  107.         while (*++p);
  108.     else
  109.         *p = '\0';        /* delete '%' comments */
  110.     string = strip_white(string);
  111.     }
  112.     return string;
  113. }
  114.  
  115.  
  116. /*
  117.  * escape: copy string 'in' to string 'out', escaping the characters \ and ";
  118.  * return pointer to 'out'
  119.  */
  120. char *
  121. #ifdef PROTOS
  122. escape(char *out,
  123.        char *in)
  124. #else
  125. escape(out, in)
  126.     char *out, *in;
  127. #endif
  128. {
  129.    char c, *sv_out = out;
  130.  
  131.    for (; c = *in; *out++ = *in++)
  132.        if (c == '\\' || c == '"')
  133.       *out++ = '\\';
  134.  
  135.    *out = '\0';
  136.    return sv_out;
  137. }
  138.  
  139.  
  140. int
  141. #ifdef PROTOS
  142. main(int argc,
  143.      char *argv[])
  144. #else
  145. main(argc, argv)
  146.     int argc;
  147.     char *argv[];
  148. #endif
  149. {
  150.     FILE *in, *out;
  151.     char line[256], line2[512], *L, *array, *p, blockname[80];
  152.     int in_initial_comments, in_block, lineno;
  153.  
  154.     /* retrieve arguments and attempt to open input and output files */
  155.  
  156.     if (argc < 3 || argc > 4) {
  157.        fprintf(stderr, "usage: %s <infile>.ps <outfile>.h [<arrayname>]\n",
  158.         argv[0]);
  159.        exit(-1); }
  160.     
  161.     in = fopen(argv[1], "r");
  162.     if (NULL == in) {
  163.        fprintf(stderr, "%s: couldn't open %s\n", argv[0], argv[1]);
  164.        exit(-1); }
  165.     
  166.     out = fopen(argv[2], "w");
  167.     if (NULL == out) {
  168.        fprintf(stderr, "%s: couldn't open %s\n", argv[0], argv[2]);
  169.        exit(-1); }
  170.     
  171.     array = argc == 4 ? argv[3] : ARRAY_NAME;
  172.  
  173.     /* print topline comment on output file */
  174.  
  175.     fprintf (out, "/*\n * %s: automatically generated by %s from %s\n",
  176.        argv[2], argv[0], argv[1]);
  177.     fprintf (out, " *\n *\tDO NOT EDIT THIS FILE!\n *\n");
  178.  
  179.     /*
  180.      * main loop - copy lines from input file, to output file, preserving
  181.      * only initial block of comments and blank lines and skipping
  182.      * over #BEGIN..#END blocks
  183.      */
  184.  
  185.     in_block = FALSE;
  186.     in_initial_comments = TRUE;
  187.     for (lineno = 1; fgets(line, 255, in) != NULL; lineno++ ) {
  188.        L = strip_white(line);            /* strip whitespace */
  189.  
  190.        if ( IS_POSTSCRIPT(L) ||            /* PostScript source or */
  191.         IS_PSCOMMENT(L) ) {            /* comment to propagate? */
  192.       if ( in_initial_comments ) {        /* first PS line? */
  193.          in_initial_comments = FALSE;
  194.          fprintf(out, " */\n\nchar *%s[] = {\n", array);
  195.       }
  196.       if (IS_PSCOMMENT(L))
  197.          L++;                /* drop first % from %% */
  198.       else
  199.          L = strip_comment(L);        /* strip trailing comment */
  200.       if (IS_BEGIN(L)) {
  201.          if (in_block) {
  202.         fprintf(stderr, "%s: #BEGIN nesting error in %s (line %d)\n",
  203.             argv[0], argv[1], lineno);
  204.         exit(-1);
  205.          }
  206.          in_block = TRUE;
  207.       }
  208.       else if (IS_END(L)) {
  209.          if (!in_block) {
  210.         fprintf(stderr, "%s: #END nesting error in %s (line %d)\n",
  211.             argv[0], argv[1], lineno);
  212.         exit(-1);
  213.          }
  214.          in_block = FALSE;
  215.       }
  216.       else if (!in_block) { 
  217.          L = escape(line2, L);
  218.          fprintf(out, "  \"%s\",\n", L);
  219.       }
  220.        } else
  221.       /* blank or comment line - copy only if in initial comment block */
  222.       if ( in_initial_comments )
  223.          fprintf(out, " * %s\n", L);
  224.     }
  225.  
  226.     fprintf(out, "  (char *)0,\n};\n");        /* terminate array decl */
  227.  
  228.     if (in_block) {        /* unterminated block? */
  229.        fprintf(stderr, "%s: unterminated #BEGIN..#END block in %s\n",
  230.            argv[0], argv[1]);
  231.        exit(-1);
  232.     }
  233.  
  234.     /*
  235.      * second loop - copy only lines within #BEGIN .. #END blocks
  236.      */
  237.  
  238.     fseek(in, 0L, SEEK_SET);            /* rewind */
  239.     in_block = FALSE;
  240.     blockname[0] = '\0';
  241.     
  242.     while ( fgets(line, 255, in) != NULL ) {
  243.        L = strip_white(line);            /* strip whitespace */
  244.        if ( IS_POSTSCRIPT(L) ) {
  245.       L = strip_comment(L);            /* strip trailing comment */
  246.       if (IS_BEGIN(L)) {
  247.          in_block = TRUE;
  248.          for (p = L + strlen(BEGIN_STR); *p && IS_WHITESPACE(*p); p++)
  249.         ;
  250.          fprintf(out, "\nchar *%s[] = {\n", p);
  251.          strcpy(blockname, p);
  252.       }
  253.       else if (IS_END(L)) {
  254.              fprintf(out, "  (char *)0,\n};\n"); /* terminate array decl */
  255.          in_block = FALSE;
  256.       }
  257.       else if (in_block) { 
  258.          /* copy PostScript to output file; add block name to first line */
  259.          L = escape(line2, L);
  260.          fprintf(out, "  \"%s", L);
  261.          if (blockname[0] && !strchr(L, '%'))
  262.         fprintf(out, "\\t\\t\\t%% %s", blockname);
  263.          blockname[0] = '\0';
  264.          fprintf(out, "\",\n");
  265.       }
  266.        }
  267.     }
  268.  
  269.     fclose(out);            /* close files and exit */
  270.     fclose(in);
  271.     exit (0);
  272. }
  273.